import * as THREE from "three";

/**
 * 顶层地图层类
 */
export class TopMapLayer {
  constructor(scene, projection, textureLoader, data) {
    this.scene = scene;
    this.projection = projection;
    this.mapObject = new THREE.Object3D(); // 地图对象容器
    this.labelContainer = new THREE.Object3D(); // 标签容器

    // 处理数据结构 - 将数组格式转为对象格式 {地区名: 数值}
    this.processedData = {};
    this.maxValue = 0;

    if (data && Array.isArray(data)) {
      // 数组格式数据处理
      data.forEach((item) => {
        if (item.name && item.value !== undefined) {
          this.processedData[item.name] = item.value;
          if (item.value > this.maxValue) {
            this.maxValue = item.value;
          }
        }
      });
    } else if (data && data.features) {
      // 兼容原来的对象格式数据
      this.processedData = data.features;
      const values = Object.values(data.features);
      this.maxValue = Math.max(...values);
    }

    // 保留原始数据引用
    this.data = data;
  }

  /**
   * 从GeoJSON数据创建地图
   * @param {Object} jsonData GeoJSON数据
   */
  createFromGeoJson(jsonData) {
    if (!jsonData || !jsonData.features) return;

    const features = jsonData.features;

    features.forEach((feature) => {
      // 单个省份
      const province = new THREE.Object3D();

      // 数据整合
      province.properties = feature.properties.name;
      const coordinates = feature.geometry.coordinates;

      // 多个多边形
      if (feature.geometry.type === "MultiPolygon") {
        coordinates.forEach((coordinate) => {
          coordinate.forEach((rows) => {
            const mesh = this.drawExtrudeMesh(rows, feature);
            province.add(mesh);

            const line = this.lineDraw(rows, "#35486E");
            province.add(line);
          });
        });
      }

      // 单个多边形
      if (feature.geometry.type === "Polygon") {
        coordinates.forEach((coordinate) => {
          const mesh = this.drawExtrudeMesh(coordinate, feature);
          province.add(mesh);

          const line = this.lineDraw(coordinate, "#35486E");
          province.add(line);
        });
      }

      this.mapObject.add(province);

      // 添加地区名称标签
      if (feature.properties && feature.properties.centroid) {
        this.createLabel(feature.properties.name, feature.properties.centroid);
      }
    });

    // 将顶层地图对象定位在最上面（添加Z轴偏移）
    this.mapObject.position.z = 1.2; // 基础层0.3 + 中间层1.3 = 1.6
    this.labelContainer.position.z = 1.3; // 标签放在地图上方

    // 将地图对象和标签容器添加到场景
    this.scene.add(this.mapObject);
    this.scene.add(this.labelContainer);
  }

  /**
   * 创建文本标签
   * @param {string} text 文本内容
   * @param {Array} position 位置坐标 [经度, 纬度]
   */
  createLabel(text, position) {
    // 创建Canvas
    const canvas = document.createElement("canvas");
    const context = canvas.getContext("2d");
    canvas.width = 256;
    canvas.height = 64;

    // 设置文本样式
    context.font = "bold 24px Consolas";
    context.fillStyle = "rgba(0,0,0,0)";
    context.fillRect(0, 0, canvas.width, canvas.height);

    // 绘制文本阴影
    context.fillStyle = "#c92704";
    context.shadowColor = "#000000";
    context.shadowBlur = 3;
    context.shadowOffsetX = 1;
    context.shadowOffsetY = 1;
    context.fillText(text, 128, 32);

    // 绘制文本
    context.fillStyle = "#ffffff";
    context.fillText(text, 128, 32);

    // 创建纹理
    const texture = new THREE.CanvasTexture(canvas);
    texture.needsUpdate = true;

    // 创建精灵材质
    const spriteMaterial = new THREE.SpriteMaterial({
      map: texture,
      transparent: true,
    });

    // 创建精灵对象
    const sprite = new THREE.Sprite(spriteMaterial);

    // 设置位置
    const [x, y] = this.projection(position);
    sprite.position.set(x, -y, 0.2); // 在地图上方0.2单位

    // 设置缩放
    sprite.scale.set(2, 0.5, 1);

    // 添加到标签容器
    this.labelContainer.add(sprite);
  }

  /**
   * 绘制立体几何
   * @param {Array} polygon 多边形点数组
   * @param {Object} feature 地理要素数据，包含属性信息
   * @returns {THREE.Mesh} 网格对象
   */
  drawExtrudeMesh(polygon, feature) {
    const shape = new THREE.Shape();

    polygon.forEach((row, i) => {
      const [x, y] = this.projection(row);

      if (i === 0) {
        shape.moveTo(x, -y);
      }
      shape.lineTo(x, -y);
    });

    // 挤压缓冲几何 - 顶层高度为0.5
    const geometry = new THREE.ExtrudeGeometry(shape, {
      depth: 0.1,
      bevelEnabled: false,
    });

    // 获取当前地区的数据值
    let value = 0;
    if (feature && feature.properties && feature.properties.name) {
      // 从处理后的数据对象中获取值
      value = this.processedData[feature.properties.name] || 0;
    }

    // 数值比例
    const ratio = this.maxValue > 0 ? value / this.maxValue : 0;

    // 记录数据检查 - 仅用于调试
    console.log(
      `地区: ${feature?.properties?.name}, 值: ${value}, 比例: ${ratio}`
    );

    // 颜色计算 - 彩虹色谱(更偏蓝色系的配色)，数据越大颜色越偏红
    // 定义颜色节点
    const colors = [
      new THREE.Color("#0047AB"), // 深蓝色 - 钴蓝色 - 最低值
      new THREE.Color("#20B2AA"), // 蓝绿色 - 浅海绿色
      new THREE.Color("#FADA5E"), // 淡黄色 - 淡金菊色
      new THREE.Color("#FF7F00"), // 橙色
      new THREE.Color("#FF0000"), // 红色 - 最高值
    ];

    // 调整色谱分布，让蓝色区域占据更大比例
    const adjustedRatio = Math.pow(ratio, 1.5); // 使用幂函数调整，增加低值(蓝色)区域比例

    // 根据调整后的数据比例确定在哪个颜色区间
    let colorIndex = Math.min(Math.floor(adjustedRatio * 4), 3);
    let localRatio = adjustedRatio * 4 - colorIndex;

    // 在两个相邻颜色之间插值
    const color = new THREE.Color();
    color.r =
      colors[colorIndex].r +
      (colors[colorIndex + 1].r - colors[colorIndex].r) * localRatio;
    color.g =
      colors[colorIndex].g +
      (colors[colorIndex + 1].g - colors[colorIndex].g) * localRatio;
    color.b =
      colors[colorIndex].b +
      (colors[colorIndex + 1].b - colors[colorIndex].b) * localRatio;

    // 使用MeshStandardMaterial代替MeshPhysicalMaterial
    const material = new THREE.MeshPhysicalMaterial({
      color: color,
      clearcoat: 0,
      reflectivity: 0.1,
      ior: 1.0,
      roughness: 0.8,
      metalness: 0.1,
      transparent: false,
    });

    return new THREE.Mesh(geometry, material);
  }

  /**
   * 绘制边框 线
   * @param {*} polygon 多边形 点数组
   * @param {*} color 材质颜色
   */
  lineDraw(polygon, color) {
    const lineGeometry = new THREE.BufferGeometry();
    const pointsArray = new Array();

    polygon.forEach((row) => {
      const [x, y] = this.projection(row);
      pointsArray.push(new THREE.Vector3(x, -y, 0.11));
    });
    lineGeometry.setFromPoints(pointsArray);

    const lineMaterial = new THREE.LineBasicMaterial({
      color: color,
      linewidth: 10,
    });

    return new THREE.Line(lineGeometry, lineMaterial);
  }

  /**
   * 清理资源
   */
  dispose() {
    if (this.mapObject) {
      this.scene.remove(this.mapObject);

      // 递归遍历所有子对象并释放几何体和材质
      this.mapObject.traverse((obj) => {
        if (obj.isMesh) {
          if (obj.geometry) obj.geometry.dispose();
          if (obj.material) {
            if (Array.isArray(obj.material)) {
              obj.material.forEach((mat) => mat.dispose());
            } else {
              obj.material.dispose();
            }
          }
        }
      });
    }

    // 清理标签容器
    if (this.labelContainer) {
      this.scene.remove(this.labelContainer);

      // 释放标签资源
      this.labelContainer.traverse((obj) => {
        if (obj.isSprite && obj.material) {
          if (obj.material.map) obj.material.map.dispose();
          obj.material.dispose();
        }
      });
    }
  }
}
